// IndexedDB 工具函数

// 数据库配置
const DB_NAME = 'RunningApp';
const DB_VERSION = 1;
const RECORDS_STORE = 'runRecords';
const MAPS_STORE = 'offlineMaps';
const MAP_TILES_STORE = 'mapTiles';

// 打开数据库
const openDatabase = (): Promise<IDBDatabase> => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);
    
    request.onerror = () => reject(request.error);
    request.onsuccess = () => resolve(request.result);
    
    request.onupgradeneeded = (event) => {
      const db = request.result;
      
      // 创建运动记录存储
      if (!db.objectStoreNames.contains(RECORDS_STORE)) {
        const recordStore = db.createObjectStore(RECORDS_STORE, { keyPath: 'id' });
        recordStore.createIndex('date', 'date', { unique: false });
      }
      
      // 创建离线地图存储
      if (!db.objectStoreNames.contains(MAPS_STORE)) {
        const mapStore = db.createObjectStore(MAPS_STORE, { keyPath: 'id' });
        mapStore.createIndex('name', 'name', { unique: false });
      }
      
      // 创建地图瓦片存储
      if (!db.objectStoreNames.contains(MAP_TILES_STORE)) {
        const tileStore = db.createObjectStore(MAP_TILES_STORE, { keyPath: 'key' });
        tileStore.createIndex('areaId', 'areaId', { unique: false });
      }
    };
  });
};

// 保存数据到指定存储
export const saveToStore = async <T>(storeName: string, data: T): Promise<void> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(storeName, 'readwrite');
      const store = transaction.objectStore(storeName);
      
      // 预处理数据，确保所有数据都可以被结构化克隆算法处理
      let processedData: any;
      
      if (storeName === RECORDS_STORE) {
        // 对RunRecord类型数据特殊处理
        const record = data as any;
        processedData = {
          ...record,
          // 将复杂数组转换为可序列化的简单对象
          path: record.path ? JSON.parse(JSON.stringify(record.path)) : [],
          elevationData: record.elevationData ? JSON.parse(JSON.stringify(record.elevationData)) : [],
          // 确保其他可能包含不可克隆对象的字段也被处理
          aiAnalysis: record.aiAnalysis ? JSON.parse(JSON.stringify(record.aiAnalysis)) : undefined
        };
      } else if (storeName === MAP_TILES_STORE) {
        // 对地图瓦片数据特殊处理
        const tile = data as any;
        
        // 检查tile.data类型，确保它可以被IndexedDB结构化克隆
        let tileData = tile.data;
        // Blob和ArrayBuffer可以被IndexedDB直接存储，不需要特殊处理
        // 但其他复杂对象可能需要序列化
        if (!(tileData instanceof Blob) && 
            !(tileData instanceof ArrayBuffer) && 
            typeof tileData === 'object' && 
            tileData !== null) {
          try {
            // 尝试将复杂对象转换为可序列化形式
            tileData = JSON.parse(JSON.stringify(tileData));
          } catch (e) {
            console.warn('无法序列化瓦片数据，使用原始数据');
          }
        }
        
        processedData = {
          ...tile,
          data: tileData
        };
      } else {
        // 其他类型数据，尝试通过JSON序列化/反序列化确保可克隆
        processedData = JSON.parse(JSON.stringify(data));
      }
      
      const request = store.put(processedData);
      
      request.onsuccess = () => resolve();
      request.onerror = (event) => {
        console.error('IndexedDB存储错误:', event);
        reject(request.error);
      };
      
      transaction.oncomplete = () => db.close();
    });
  } catch (error) {
    console.error(`保存到${storeName}失败:`, error);
    throw error;
  }
};

// 从存储中获取所有数据
export const getAllFromStore = async <T>(storeName: string): Promise<T[]> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(storeName, 'readonly');
      const store = transaction.objectStore(storeName);
      const request = store.getAll();
      
      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
      
      transaction.oncomplete = () => db.close();
    });
  } catch (error) {
    console.error(`从${storeName}获取数据失败:`, error);
    return [];
  }
};

// 删除存储中的数据
export const deleteFromStore = async (storeName: string, key: string | number): Promise<void> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(storeName, 'readwrite');
      const store = transaction.objectStore(storeName);
      const request = store.delete(key);
      
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
      
      transaction.oncomplete = () => db.close();
    });
  } catch (error) {
    console.error(`从${storeName}删除数据失败:`, error);
    throw error;
  }
};

// 删除存储中的所有与areaId相关的瓦片
export const deleteTilesByAreaId = async (areaId: string): Promise<void> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(MAP_TILES_STORE, 'readwrite');
      const store = transaction.objectStore(MAP_TILES_STORE);
      const index = store.index('areaId');
      const request = index.openCursor(IDBKeyRange.only(areaId));
      
      request.onsuccess = (event) => {
        const cursor = request.result;
        if (cursor) {
          cursor.delete();
          cursor.continue();
        }
      };
      
      transaction.oncomplete = () => {
        db.close();
        resolve();
      };
      
      transaction.onerror = () => reject(transaction.error);
    });
  } catch (error) {
    console.error('删除瓦片数据失败:', error);
    throw error;
  }
};

// 导出常量
export { RECORDS_STORE, MAPS_STORE, MAP_TILES_STORE };